//
//  LYThridPartTool.m
//  LYDevelopKit
//
//  Created by 李阳 on 2018/5/28.
//

#import "FTGPlatformTool.h"

#import <GoogleSignIn/GoogleSignIn.h>
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <FBSDKLoginKit/FBSDKLoginKit.h>
#import <TwitterCore/TwitterCore.h>
#import <TwitterKit/TwitterKit.h>

static NSString *const kDomain = @"FTGPlatformTool.Domain";

/// 启动时的错误
typedef NS_ENUM(NSUInteger, _LYFireErrorType) {
    _LYFireUninject, ///< 未注入
    _LYFireCancelled, ///< 取消
    _LYFireTokenError, ///< token错误
};


@interface FTGPlatformResult ()

/// 头像地址
@property (nonatomic, strong)NSURL *iconUrl;

- (instancetype)initWithFBSDKLoginManagerLoginResult:(FBSDKLoginManagerLoginResult *)result;
- (void)syncWithFBSDKProfile:(FBSDKProfile *)profile;


- (instancetype)initWithTWTRSession:(TWTRSession *)session;
- (void)syncWithTWTRUser:(TWTRUser *)user;


- (instancetype)initWithGIDSignIn:(GIDSignIn *)signIn User:(GIDGoogleUser *)gUser;

@end

@implementation FTGPlatformResult

- (instancetype)init
{
    self = [super init];
    if (!self) return nil;
    _fullName = @"your_nikename";
    _firstName = @"your_firstname";
    _lastName = @"your_lastname";
    return self;
}


- (instancetype)initWithFBSDKLoginManagerLoginResult:(FBSDKLoginManagerLoginResult *)result
{
    self = [self init];
    
    _platformType = FTGPlatformFacebook;
    
    FBSDKAccessToken *token = result.token;
    _userId = token.userID;
    _token = token.tokenString;
    _refreshDate = token.refreshDate;
    _expirationDate = token.expirationDate;
    _permissions = token.permissions;
    
    return self;
}
- (void)syncWithFBSDKProfile:(FBSDKProfile *)profile
{
    _firstName = profile.firstName;
    _lastName = profile.lastName;
    _fullName = profile.name;
    _iconUrl = [profile imageURLForPictureMode:FBSDKProfilePictureModeSquare size:(CGSize){100,100}];
}


- (instancetype)initWithTWTRSession:(TWTRSession *)session
{
    self = [self init];
    
    _platformType = FTGPlatformTwitter;
    
    _userId = session.userID;
    _token = session.authToken;
    _secret = session.authTokenSecret;
    _fullName = session.userName;
    
    return self;
}
- (void)syncWithTWTRUser:(TWTRUser *)user
{
    _iconUrl = [NSURL URLWithString:user.profileImageURL];
}


- (instancetype)initWithGIDSignIn:(GIDSignIn *)signIn User:(GIDGoogleUser *)user
{
    self = [self init];
    
    _platformType = FTGPlatformGoogle;
    
    GIDAuthentication *authentication = user.authentication;
    
    _userId = authentication.clientID;
    _token = authentication.idToken;
    _expirationDate = authentication.accessTokenExpirationDate;
    
    GIDProfileData *profile = user.profile;
    
    if (profile.hasImage)
    {
        _iconUrl = [profile imageURLWithDimension:200];
    }
    
    _email = profile.email;
    _fullName = profile.name;
    _firstName = profile.givenName;
    _lastName = profile.familyName;
    
    return self;
}

@end

@interface FTGPlatformTool ()<GIDSignInDelegate, GIDSignInUIDelegate>

@property(nonatomic, strong) FBSDKLoginManager *fbLoginManager;

/// 是否注入twitter
@property (nonatomic, assign, getter=hasInjectTwitter)BOOL injectTwitter;

/// 是否注入Google
@property (nonatomic, assign, getter=hasInjectGoogle)BOOL injectGoogle;

/// 谷歌启动回调
@property (nonatomic, copy)void(^fireGoogleBlock)(FTGPlatformResult *result, NSError *error);

@end

@implementation FTGPlatformTool


#pragma mark - 注入模块
/// 注册谷歌模块
- (void)injectGoolgeModuleWithClientID:(NSString *)clientID
{
    [GIDSignIn sharedInstance].clientID = clientID;
    _injectGoogle = YES;
}
/// 注册Facebook模块
- (void)injectFaceBookLogin
{
    
}
/// 注册Twitter模块
- (void)injectTwitterLoginWithKey:(NSString *)key
                             secret:(NSString *)secret
{
    [[Twitter sharedInstance] startWithConsumerKey:key consumerSecret:secret];
    _injectTwitter = YES;
}

#pragma mark - 启动模块

- (void)fireWithPlatformType:(FTGPlatformType)type viewController:(UIViewController *)vc completion:(void(^)(FTGPlatformResult *result, NSError *error))completion
{
    
    NSError *(^errorGenerator)(NSInteger, NSString *) = ^(NSInteger code, NSString *msg) {
        return [[NSError alloc]initWithDomain:kDomain code:code userInfo:@{@"message":msg}];
    };
    
    switch (type)
    {
        case FTGPlatformFacebook:
        {
            if (!self.fbLoginManager)
            {
                !completion ?: completion(nil, errorGenerator(_LYFireUninject,@"Uninjected Facebook module"));
                return;
            }
            
            [self.fbLoginManager logOut];
            NSArray *permissions = @[@"public_profile",@"email",@"user_birthday",@"user_photos",@"user_about_me"];
            [self.fbLoginManager logInWithReadPermissions:permissions fromViewController:vc handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
                if (error)
                {
                    !completion ?: completion(nil, error);
                }
                else
                {
                    
                    if (result.isCancelled)
                    {
                        !completion ?: completion(nil, errorGenerator(_LYFireCancelled,@"Cancelled"));
                        return;
                    }
                    
                    if (!result.token.tokenString.length)
                    {
                        !completion ?: completion(nil, errorGenerator(_LYFireTokenError,@"Token is error"));
                        return;
                    }
                    
                    FTGPlatformResult *fbResult = [[FTGPlatformResult alloc]initWithFBSDKLoginManagerLoginResult:result];
                    [FBSDKProfile loadCurrentProfileWithCompletion:^(FBSDKProfile *profile, NSError *error) {
                        if (error)
                        {
                            !completion ?: completion(nil, error);
                        }
                        else
                        {
                            [fbResult syncWithFBSDKProfile:profile];
                            !completion ?: completion(fbResult, nil);
                        }
                    }];
                }
            }];
            
        }
            break;
        case FTGPlatformTwitter:
        {
            if (!self.hasInjectTwitter)
            {
                !completion ?: completion(nil, errorGenerator(_LYFireUninject,@"Uninjected Twitter module"));
                return;
            }
            
            [[Twitter sharedInstance]logInWithCompletion:^(TWTRSession * _Nullable session, NSError * _Nullable error) {
                if (error)
                {
                    /// 取消操作error有值
                    !completion ?: completion(nil, error);
                }
                else
                {
                    if (session.authToken && session.authTokenSecret)
                    {
                        FTGPlatformResult *result = [[FTGPlatformResult alloc]initWithTWTRSession:session];
                        
                        TWTRAPIClient *client = [TWTRAPIClient clientWithCurrentUser];
                        [client loadUserWithID:session.userID completion:^(TWTRUser * _Nullable user, NSError * _Nullable error) {
                            if (error)
                            {
                                !completion ?: completion(nil, error);
                            }
                            else
                            {
                                [result syncWithTWTRUser:user];
                                !completion ?: completion(result, nil);
                            }
                        }];
                        
                    }
                    else
                    {
                        !completion ?: completion(nil, errorGenerator(_LYFireTokenError,@"Token is error"));
                    }
                }
            }];
            
        }
            break;
        case FTGPlatformGoogle:
        {
            if (!self.hasInjectGoogle)
            {
                !completion ?: completion(nil, errorGenerator(_LYFireUninject,@"Uninjected Google module"));
                return;
            }
            
            self.fireGoogleBlock = completion;
            
            GIDSignIn *signIn = [GIDSignIn sharedInstance];
            signIn.shouldFetchBasicProfile = YES;
            signIn.delegate = self;
            signIn.uiDelegate = self;
            [signIn signIn];
            
        }
            break;
            
        default:
            break;
    }
}

#pragma mark - GIDSignInDelegate

- (void)signIn:(GIDSignIn *)signIn didSignInForUser:(GIDGoogleUser *)user withError:(NSError *)error
{
    
    if (!self.fireGoogleBlock) return;
    
    if (error) {
        self.fireGoogleBlock(nil, error);
    } else {
        FTGPlatformResult *result = [[FTGPlatformResult alloc]initWithGIDSignIn:signIn User:user];
        self.fireGoogleBlock(result, nil);
    }
    self.fireGoogleBlock = nil;
}
- (void)signIn:(GIDSignIn *)signIn didDisconnectWithUser:(GIDGoogleUser *)user withError:(NSError *)error
{
    
}

#pragma mark - GIDSignInUIDelegate

- (void)signInWillDispatch:(GIDSignIn *)signIn error:(NSError *)error
{
    
}
- (void)signIn:(GIDSignIn *)signIn presentViewController:(UIViewController *)viewController
{
    
}
- (void)signIn:(GIDSignIn *)signIn dismissViewController:(UIViewController *)viewController
{
    
}


- (BOOL)facebookDidFinishLaunchingWithApplication:(UIApplication *)app options:(NSDictionary *)options
{
    self.fbLoginManager = [[FBSDKLoginManager alloc] init];
    [[FBSDKApplicationDelegate sharedInstance] application:app didFinishLaunchingWithOptions:options];
    return YES;
}


- (BOOL) application:(UIApplication *)application
           handleURL:(NSURL *)url
   sourceApplication:(NSString *)sourceApplication
          annotation:(id)annotation
{
    if ([sourceApplication isEqualToString:@"com.facebook.Facebook"])
    {
        [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
    }
    else if ([[url absoluteString] hasPrefix:@"com.google"])
    {
        [[GIDSignIn sharedInstance] handleURL:url sourceApplication:sourceApplication annotation:annotation];
    }
    return YES;
}



#pragma mark - Singleton
+ (instancetype)defaultTool
{
    return [[[self class]alloc]init];
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
    static FTGPlatformTool *tool_;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        tool_ = [super allocWithZone:zone];
    });
    return tool_;
}

- (id)copyWithZone:(NSZone *)zone
{
    return self;
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
    return self;
}
@end




